package com.ttg.utils.sm;


import sun.misc.BASE64Encoder;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SM4Utils {
    private static String secretKey = "";

    private static String iv = "";

    private static boolean hexString = true;

    public SM4Utils() {
    }

    public void SetSecretKey(String Key) {
        this.secretKey = Key;
    }


    public static String encryptDataECB(String plainText, String key) {
        secretKey = key;
        return encryptDataECB(plainText);
    }

    public static String encryptDataECB(String plainText) {
        return encryptDataECB(plainText, secretKey,false,true,true);
    }

    public static String encryptDataECB(String plainText, String secretKey,boolean isNoPadding,boolean isBase64,boolean isKeyHex) {
        hexString = true;
        try {
            SM4_Context ctx = new SM4_Context();
            if(isNoPadding){
                ctx.isPadding = false;
            }else{
                ctx.isPadding = true;
            }
            ctx.mode = SM4.SM4_ENCRYPT;

            byte[] keyBytes;
            if (isKeyHex) {
                keyBytes = Util.hexStringToBytes(secretKey);
            } else {
                keyBytes = secretKey.getBytes();
            }

            SM4 sm4 = new SM4();
            sm4.sm4_setkey_enc(ctx, keyBytes);
            byte[] encrypted = sm4.sm4_crypt_ecb(ctx, plainText.getBytes("UTF-8"));

//			String cipherText = Util.encodeHexString(encrypted);
            //默认返回base64
            String cipherText = null;
            if (isBase64)
                cipherText = Base64Util.encodeData(encrypted);
            else
                cipherText = CryptoUtil.bin2hex(encrypted);

            //String cipherText = new String(encrypted);
            //Log.e("test1",cipherText);
			/*
			String cipherText = new BASE64Encoder().encode(encrypted);
			if (cipherText != null && cipherText.trim().length() > 0)
			{
				Pattern p = Pattern.compile("\\s*|\t|\r|\n");
				Matcher m = p.matcher(cipherText);
				cipherText = m.replaceAll("");
			}*/
            return cipherText;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public String decryptDataECB(String cipherText, String secretKey,boolean isNoPadding, boolean isInputHex, boolean isHexFormat,boolean isKeyHex) {
        try {
            SM4_Context ctx = new SM4_Context();
            if(isNoPadding){
                ctx.isPadding = false;
            }else {
                ctx.isPadding = true;
            }
            ctx.mode = SM4.SM4_DECRYPT;

            byte[] keyBytes;
            if (isKeyHex) {
                keyBytes = Util.hexStringToBytes(secretKey);
            } else {
                keyBytes = secretKey.getBytes();
            }

            SM4 sm4 = new SM4();
            sm4.sm4_setkey_dec(ctx, keyBytes);
            byte[] decryptData = null;
            if (isInputHex) {
                decryptData = CryptoUtil.hex2bin(cipherText);
            } else {
                decryptData = Base64Util.decodeData(cipherText);
            }
            byte[] decrypted = sm4.sm4_crypt_ecb(ctx, decryptData);
            String returnData22 = CryptoUtil.bin2hex(decrypted);
            String returnData = null;
            if (isHexFormat) {
                returnData = CryptoUtil.bin2hex(decrypted);
            } else {
                returnData = new String(decrypted, "UTF-8");
            }
            return returnData;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public String encryptDataCBC(String plainText, String key, byte[] ivBytes) {
        return encryptDataCBC(plainText, key, ivBytes, false, false,true);
    }

    public String encryptDataCBC(String plainText) {
        return encryptDataCBC(plainText, secretKey, CryptoUtil.hex2bin(iv), false, false ,true);
    }

    public String encryptDataCBC(String plainText, String key, byte[] ivBytes, boolean isNoPadding, boolean isBase64 ,boolean isKeyHex) {
        this.secretKey = key;
//		hexString=false;
        hexString = true;

        try {
            SM4_Context ctx = new SM4_Context();
            if (isNoPadding) {
                ctx.isPadding = false;
            } else {
                ctx.isPadding = true;//20210330设置成填充模式
            }
            ctx.mode = SM4.SM4_ENCRYPT;


            byte[] keyBytes;
            if (isKeyHex) {
                keyBytes = Util.hexStringToBytes(secretKey);
//				ivBytes = Util.hexStringToBytes(iv);
            } else {
                keyBytes = secretKey.getBytes();
//				ivBytes = iv.getBytes();
            }

            SM4 sm4 = new SM4();
            sm4.sm4_setkey_enc(ctx, keyBytes);
            byte[] encrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, plainText.getBytes("UTF-8"));
            String cipherText = null;
            if (isBase64) {
                cipherText = new BASE64Encoder().encode(encrypted);
            } else {
                cipherText = CryptoUtil.bin2hex(encrypted);
            }
            if (cipherText != null && cipherText.trim().length() > 0) {
                Pattern p = Pattern.compile("\\s*|\t|\r|\n");
                Matcher m = p.matcher(cipherText);
                cipherText = m.replaceAll("");
            }
            return cipherText;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    public String encryptData_CBC(String plainText,String key,byte[] ivBytes)
    {

        this.secretKey = key;
        hexString=false;
        try
        {
            SM4_Context ctx = new SM4_Context();
            ctx.isPadding = true;//20210330设置成填充模式
            ctx.mode = SM4.SM4_ENCRYPT;


            byte[] keyBytes;
            if (hexString)
            {
                keyBytes = Util.hexStringToBytes(secretKey);
//				ivBytes = Util.hexStringToBytes(iv);
            }
            else
            {
                keyBytes = secretKey.getBytes();
//				ivBytes = iv.getBytes();
            }

            SM4 sm4 = new SM4();
            sm4.sm4_setkey_enc(ctx, keyBytes);
            byte[] encrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, plainText.getBytes("UTF-8"));
            String cipherText = new BASE64Encoder().encode(encrypted);
            if (cipherText != null && cipherText.trim().length() > 0)
            {
                Pattern p = Pattern.compile("\\s*|\t|\r|\n");
                Matcher m = p.matcher(cipherText);
                cipherText = m.replaceAll("");
            }
            return cipherText;
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 星沙专用重构方法
     * @param plainText
     * @param key
     * @param iv2
     * @return
     */
    public String encryptData_CBC(String plainText,String key,String iv2)
    {
        this.iv=iv2;
        this.secretKey = key;
        hexString=false;
        try
        {
            SM4_Context ctx = new SM4_Context();
            ctx.isPadding = true;//20210330设置成填充模式
            ctx.mode = SM4.SM4_ENCRYPT;

            byte[] keyBytes;
            byte[] ivBytes;
            if (hexString)
            {
                keyBytes = Util.hexStringToBytes(secretKey);
                ivBytes = Util.hexStringToBytes(iv);
            }
            else
            {
                keyBytes = secretKey.getBytes();
                ivBytes = iv.getBytes();
            }

            SM4 sm4 = new SM4();
            sm4.sm4_setkey_enc(ctx, keyBytes);
            byte[] encrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, plainText.getBytes("UTF-8"));
            String cipherText = new BASE64Encoder().encode(encrypted);
            if (cipherText != null && cipherText.trim().length() > 0)
            {
                Pattern p = Pattern.compile("\\s*|\t|\r|\n");
                Matcher m = p.matcher(cipherText);
                cipherText = m.replaceAll("");
            }
            return cipherText;
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }


    public String decryptDataCBC(String cipherText) {
        try {
            SM4_Context ctx = new SM4_Context();
            ctx.isPadding = true;
            ctx.mode = SM4.SM4_DECRYPT;

            byte[] keyBytes;
            byte[] ivBytes;
            if (hexString) {
                keyBytes = Util.hexStringToBytes(secretKey);
                ivBytes = Util.hexStringToBytes(iv);
            } else {
                keyBytes = secretKey.getBytes();
                ivBytes = iv.getBytes();
            }

            SM4 sm4 = new SM4();
            sm4.sm4_setkey_dec(ctx, keyBytes);
//            byte[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, new BASE64Decoder().decodeBuffer(cipherText));
            byte[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, Base64Util.decodeData(cipherText));
            return new String(decrypted, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    public String decryptDataCBC(String cipherText, String secretKey, String iv, boolean isNoPadding,boolean isInputHex, boolean isHexFormat,boolean isKeyHex) {
        try {
            SM4_Context ctx = new SM4_Context();
            if(isNoPadding){
                ctx.isPadding = false;
            }else {
                ctx.isPadding = true;
            }
            ctx.mode = SM4.SM4_DECRYPT;

            byte[] keyBytes;
            byte[] ivBytes;
            if (isKeyHex) {
                keyBytes = Util.hexStringToBytes(secretKey);
            } else {
                keyBytes = secretKey.getBytes();
//                ivBytes = iv.getBytes();
            }
            //20231208 IV只有hex格式
            ivBytes = Util.hexStringToBytes(iv);

            SM4 sm4 = new SM4();
            sm4.sm4_setkey_dec(ctx, keyBytes);
            byte[] decryptData = null;
            if (isInputHex) {
                decryptData = CryptoUtil.hex2bin(cipherText);
            } else {
                decryptData = Base64Util.decodeData(cipherText);
            }
//            byte[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, new BASE64Decoder().decodeBuffer(cipherText));
            byte[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, decryptData);
            String returnData = null;
            if (isHexFormat) {
                returnData = CryptoUtil.bin2hex(decrypted);
            } else {
                returnData = new String(decrypted, "UTF-8");
            }

            return returnData;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /*
    public static void main(String[] args) throws IOException
    {
        String plainText = "abcd";

        SM4Utils sm4 = new SM4Utils();
        sm4.secretKey = "JeF8U9wHFOMfs2Y8";
        sm4.hexString = false;

        System.out.println("ECB模式");
        String cipherText = sm4.encryptData_ECB(plainText);
        System.out.println("密文: " + cipherText);
        System.out.println("");

        plainText = sm4.decryptData_ECB(cipherText);
        System.out.println("明文: " + plainText);
        System.out.println("");

        System.out.println("CBC模式");
        sm4.iv = "UISwD9fW6cFh9SNS";
        cipherText = sm4.encryptData_CBC(plainText);
        System.out.println("密文: " + cipherText);
        System.out.println("");

        plainText = sm4.decryptData_CBC(cipherText);
        System.out.println("明文: " + plainText);
    }*/
//    public static void SM4_ECB_TEST() throws IOException {
//
//        String plainText = "11223344556677888877665544332211";
//        String sm4_Key = "00000000000000008888888888888888";
//        SM4Utils sm4Utils = new SM4Utils();
//        sm4Utils.SetSecretKey(sm4_Key);
//        String encryptdata = sm4Utils.encryptDataECB(plainText);
//        //txt.setText(encryptdata);
//        System.out.println("密文: " + encryptdata);
//        String decryptdata = sm4Utils.decryptDataECB(encryptdata, sm4_Key, false,false, false);
//        System.out.println("密文: " + decryptdata);
//    }
}

